﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Styx.CommonBot.Routines;
using Styx.Pathing;
using Styx;
using Styx.WoWInternals.WoWObjects;
using Styx.WoWInternals;
using Styx.CommonBot;
using System.Windows.Media;
using Styx.Common;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Styx.TreeSharp;
using Action = Styx.TreeSharp.Action;
using System.Diagnostics;
using System.Threading;
using Styx.WoWInternals.Misc;

namespace MyBMHunter
{
    public partial class Main : CombatRoutine
    {
        public string LastSpell = string.Empty;
        public static string LastPetCast = string.Empty;

        public string CONCUSSIVE_SHOT = "Concussive Shot";
        public string ARCANE_SHOT = "Arcane Shot";
        public string STEADY_SHOT = "Steady Shot";
        public string COBRA_SHOT = "Cobra Shot";
        public string KILL_COMMAND = "Kill Command";
        public string FOCUS_FIRE = "Focus Fire";
        public string BESTIAL_WRATH = "Bestial Wrath";
        public string ASPECT_OF_THE_IRON_HAWK = "Aspect of the Iron Hawk";
        public string ASPECT_OF_THE_HAWK = "Aspect of the Hawk";
        public string TRAP_LAUNCHER = "Trap Launcher";
        public string DIRE_BEAST = "Dire Beast";
        public string A_MURDER_OF_CROWS = "A Murder of Crows";
        public string STAMPEDE = "Stampede";
        public string RAPID_FIRE = "Rapid Fire";
        public string GLAIVE_TOSS = "Glaive Toss";
        public string GIFT_OF_THE_NARUU = "Gift of the Naruu";
        public string BERSERKING = "Berserking";
        public string BLOOD_FURY = "Blood Fury";
        public string MISDIRECTION = "Misdirection";
        public string MULTI_SHOT = "Multi-Shot";
        public string KILL_SHOT = "Kill Shot";
        public string MEND_PET = "Mend Pet";
        public string EXPLOSIVE_TRAP = "Explosive Trap";
        public string ICE_TRAP = "Ice Trap";
        public string SNAKE_TRAP = "Snake Trap";
        public string COUNTER_SHOT = "Counter Shot";
        public string FEIGN_DEATH = "Feign Death";
        public string SERPENT_STING = "Serpent Sting";
        public string EXPLOSIVE_SHOT = "Explosive Shot";
        public string LockAndLoad = "Lock and Load";
        public string BLACK_ARROW = "Black Arrow";
        public string LIFEBLOOD = "Lifeblood";
        public string FLASK_OF_SPRING_BLOSSOMS = "Flask of Spring Blossoms";
        public string VISIONS_OF_INSANITY = "Visions of Insanity";

        public int LOCK_AND_LOAD = 56453;

        #region shots
        Composite spell()
        {
            return new Decorator(
                new Action(ret =>
                {

                }));
        }
        Composite Lifeblood()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(LIFEBLOOD)
                && CRSettingsBM.myPrefs.useLifeBlood != CRSettingsBM.CooldownPrefs.Manual
                && !spellOnCooldown(LIFEBLOOD)
                && !SpeedBuff
                && (CRSettingsBM.myPrefs.useLifeBlood == CRSettingsBM.CooldownPrefs.OnCoolDown
                || (CRSettingsBM.myPrefs.useLifeBlood == CRSettingsBM.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget))),
                new Action(ret =>
                {
                    SpellManager.Cast(LIFEBLOOD);
                    Logging.Write(Colors.Lime, LIFEBLOOD);
                    LastSpell = LIFEBLOOD;
                }));
        }
        Composite SerpentSting()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(SERPENT_STING)
                && !debuffExists(SERPENT_STING, Me.CurrentTarget)
                && Me.FocusPercent >= 15
                && LastSpell != SERPENT_STING
                && SpellManager.CanCast(SERPENT_STING),
                new Action(ret =>
                {
                    SpellManager.Cast(SERPENT_STING);
                    Logging.Write(Colors.Lime, SERPENT_STING);
                    LastSpell = SERPENT_STING;
                }));
        }
        Composite CounterShot()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.interrupt
                && SpellManager.HasSpell(COUNTER_SHOT)
                && !spellOnCooldown(COUNTER_SHOT)
                && (Me.CurrentTarget.IsCasting
                && Me.CanInterruptCurrentSpellCast)
                && LastSpell != COUNTER_SHOT
                && SpellManager.CanCast(COUNTER_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(COUNTER_SHOT);
                    Logging.Write(Colors.Lime, COUNTER_SHOT);
                    LastSpell = COUNTER_SHOT;
                }));
        }
        Composite ConcussiveShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(CONCUSSIVE_SHOT)
                && !spellOnCooldown(CONCUSSIVE_SHOT)
                && !debuffExists(CONCUSSIVE_SHOT, Me.CurrentTarget)
                && LastSpell != CONCUSSIVE_SHOT
                && SpellManager.CanCast(CONCUSSIVE_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(CONCUSSIVE_SHOT);
                    Logging.Write(Colors.Lime, CONCUSSIVE_SHOT);
                    LastSpell = CONCUSSIVE_SHOT;
                }));
        }
        Composite ConcussiveShotKiting()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.useConcussiveKiting
                && SpellManager.HasSpell(CONCUSSIVE_SHOT)
                && !spellOnCooldown(CONCUSSIVE_SHOT)
                && !debuffExists(CONCUSSIVE_SHOT, Me.CurrentTarget)
                && (Me.IsMoving
                && Me.MovementInfo.MovingBackward)
                && LastSpell != CONCUSSIVE_SHOT
                && SpellManager.CanCast(CONCUSSIVE_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(CONCUSSIVE_SHOT);
                    Logging.Write(Colors.Lime, CONCUSSIVE_SHOT);
                    LastSpell = CONCUSSIVE_SHOT;
                }));
        }
        Composite ArcaneShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(ARCANE_SHOT)
                && Me.FocusPercent >= CRSettingsBM.myPrefs.focusPercentAS
                && SpellManager.CanCast(ARCANE_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(ARCANE_SHOT);
                    Logging.Write(Colors.Lime, ARCANE_SHOT);
                    LastSpell = ARCANE_SHOT;
                }));
        }
        Composite SteadyShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(STEADY_SHOT)
                && Me.Level < 81
                && Me.FocusPercent <= CRSettingsBM.myPrefs.focusPercentSteady
                && SpellManager.CanCast(STEADY_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(STEADY_SHOT);
                    Logging.Write(Colors.Lime, STEADY_SHOT);
                    LastSpell = STEADY_SHOT;
                }));
        }
        Composite SteadyShotAoe()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(STEADY_SHOT)
                && Me.Level < 81
                && Me.FocusPercent <= CRSettingsBM.myPrefs.focusPercentSteady
                && SpellManager.CanCast(STEADY_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(STEADY_SHOT);
                    Logging.Write(Colors.LightBlue, STEADY_SHOT);
                    LastSpell = STEADY_SHOT;
                }));
        }
        Composite CobraShotAoe()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(COBRA_SHOT)
                && Me.Level >= 81
                && Me.FocusPercent <= CRSettingsBM.myPrefs.focusPercentSteady
                && SpellManager.CanCast(COBRA_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(COBRA_SHOT);
                    Logging.Write(Colors.LightBlue, COBRA_SHOT);
                    LastSpell = COBRA_SHOT;
                }));
        }
        Composite CobraShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(COBRA_SHOT)
                && Me.Level >= 81
                && Me.FocusPercent <= CRSettingsBM.myPrefs.focusPercentSteady
                && SpellManager.CanCast(COBRA_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(COBRA_SHOT);
                    Logging.Write(Colors.Lime, COBRA_SHOT);
                    LastSpell = COBRA_SHOT;
                }));
        }
        Composite KillCommand()
        {
            return new Decorator(ret => gotTarget
                && Me.Pet != null
                && SpellManager.HasSpell(KILL_COMMAND)
                && !spellOnCooldown(KILL_COMMAND)
                && (Me.GotAlivePet
                && Me.Pet.Location.Distance(Me.CurrentTarget.Location) <= 25)
                && Me.FocusPercent >= 40
                && SpellManager.CanCast(KILL_COMMAND),
                new Action(ret =>
                {
                    SpellManager.Cast(KILL_COMMAND);
                    Logging.Write(Colors.Lime, KILL_COMMAND);
                    LastSpell = KILL_COMMAND;
                }));
        }
        Composite FocusFire()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(FOCUS_FIRE)
                && buffStackCount("Frenzy", Me) >= 5
                && LastSpell != FOCUS_FIRE
                && SpellManager.CanCast(FOCUS_FIRE),
                new Action(ret =>
                {
                    SpellManager.Cast(FOCUS_FIRE);
                    Logging.Write(Colors.Lime, FOCUS_FIRE);
                    LastSpell = FOCUS_FIRE;
                }));
        }
        Composite BestialWrath()
        {
            return new Decorator(ret => gotTarget
                && Me.Pet != null
                && SpellManager.HasSpell(BESTIAL_WRATH)
                && !spellOnCooldown(BESTIAL_WRATH)
                && (Me.GotAlivePet
                && Me.Pet.Location.Distance(Me.CurrentTarget.Location) <= 5)
                && (targetExistence(Me.CurrentTarget) > 10 || IsWoWBoss(Me.CurrentTarget))
                && LastSpell != BESTIAL_WRATH
                && SpellManager.CanCast(BESTIAL_WRATH),
                new Action(ret =>
                {
                    SpellManager.Cast(BESTIAL_WRATH);
                    Logging.Write(Colors.Lime, BESTIAL_WRATH);
                    LastSpell = BESTIAL_WRATH;
                    return RunStatus.Success;
                }));
        }
        Composite GlaiveToss()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(GLAIVE_TOSS)
                && Me.FocusPercent >= 15
                && LastSpell != GLAIVE_TOSS
                && SpellManager.CanCast(GLAIVE_TOSS),
                new Action(ret =>
                {


                    if (!Me.GroupInfo.IsInParty
                        && SpellManager.HasSpell(MISDIRECTION)
                        && !spellOnCooldown(MISDIRECTION)
                        && !buffExists(MISDIRECTION, Me)
                        && !Me.CurrentTarget.Name.Contains("Dummy"))
                    {
                        Lua.DoString("RunMacroText('/cast [@focus,help][help][@pet,exists] Misdirection');");
                        SpellManager.Cast(GLAIVE_TOSS);
                        Logging.Write(Colors.Lime, GLAIVE_TOSS);
                        LastSpell = GLAIVE_TOSS;
                    }
                    else
                    {
                        SpellManager.Cast(GLAIVE_TOSS);
                        Logging.Write(Colors.Lime, GLAIVE_TOSS);
                        LastSpell = GLAIVE_TOSS;
                    }
                }));
        }
        Composite MurderOfCrows()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.useCrows != CRSettingsBM.CooldownPrefs.Manual
                && SpellManager.HasSpell(A_MURDER_OF_CROWS)
                && !spellOnCooldown(A_MURDER_OF_CROWS)
                && !debuffExists(A_MURDER_OF_CROWS, Me.CurrentTarget)
                && ((CRSettingsBM.myPrefs.useCrows == CRSettingsBM.CooldownPrefs.OnCoolDown && targetExistence(Me.CurrentTarget) > 30 && !IsWoWBoss(Me.CurrentTarget))
                || (CRSettingsBM.myPrefs.useCrows == CRSettingsBM.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                && Me.FocusPercent >= 60
                && LastSpell != A_MURDER_OF_CROWS
                && SpellManager.CanCast(A_MURDER_OF_CROWS),
                new Action(ret =>
                {
                    SpellManager.Cast(A_MURDER_OF_CROWS);
                    Logging.Write(Colors.Lime, A_MURDER_OF_CROWS);
                    LastSpell = A_MURDER_OF_CROWS;
                }));
        }
        Composite DireBeast()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(DIRE_BEAST)
                && !spellOnCooldown(DIRE_BEAST)
                && LastSpell != DIRE_BEAST
                && SpellManager.CanCast(DIRE_BEAST),
                new Action(ret =>
                {
                    SpellManager.Cast(DIRE_BEAST);
                    Logging.Write(Colors.Lime, DIRE_BEAST);
                    LastSpell = DIRE_BEAST;
                }));
        }
        Composite Stampede()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.useStampede != CRSettingsBM.CooldownPrefs.Manual
                && SpellManager.HasSpell(STAMPEDE)
                && !spellOnCooldown(STAMPEDE)
                && ((CRSettingsBM.myPrefs.useStampede == CRSettingsBM.CooldownPrefs.OnCoolDown && targetExistence(Me.CurrentTarget) > 20 && !IsWoWBoss(Me.CurrentTarget))
                || (CRSettingsBM.myPrefs.useStampede == CRSettingsBM.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                && LastSpell != STAMPEDE
                && SpellManager.CanCast(STAMPEDE),
                new Action(ret =>
                {
                    SpellManager.Cast(STAMPEDE);
                    Logging.Write(Colors.Lime, STAMPEDE);
                    LastSpell = STAMPEDE;
                }));
        }
        Composite RapidFire()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(RAPID_FIRE)
                && CRSettingsBM.myPrefs.useRapidFire != CRSettingsBM.CooldownPrefs.Manual
                && !spellOnCooldown(RAPID_FIRE)
                && !buffExists(RAPID_FIRE, Me)
                && !SpeedBuff
                && ((CRSettingsBM.myPrefs.useRapidFire == CRSettingsBM.CooldownPrefs.OnCoolDown && targetExistence(Me.CurrentTarget) > 15 && !IsWoWBoss(Me.CurrentTarget))
                || (CRSettingsBM.myPrefs.useRapidFire == CRSettingsBM.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                && LastSpell != RAPID_FIRE
                && SpellManager.CanCast(RAPID_FIRE),
                new Action(ret =>
                {
                    SpellManager.Cast(RAPID_FIRE);
                    Logging.Write(Colors.Lime, RAPID_FIRE);
                    LastSpell = RAPID_FIRE;
                }));
        }
        Composite Berserking()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.useBerserking != CRSettingsBM.CooldownPrefs.Manual
                && SpellManager.HasSpell(BERSERKING)
                && !spellOnCooldown(BERSERKING)
                && !SpeedBuff
                && (CRSettingsBM.myPrefs.useBerserking == CRSettingsBM.CooldownPrefs.OnCoolDown
                || (CRSettingsBM.myPrefs.useBerserking == CRSettingsBM.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                && LastSpell != BERSERKING
                && SpellManager.CanCast(BERSERKING),
                new Action(ret =>
                {
                    SpellManager.Cast(BERSERKING);
                    Logging.Write(Colors.Lime, BERSERKING);
                    LastSpell = BERSERKING;
                }));
        }
        Composite BloodFury()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.useBloodFury != CRSettingsBM.CooldownPrefs.Manual
                && SpellManager.HasSpell(BLOOD_FURY)
                && !spellOnCooldown(BLOOD_FURY)
                && (CRSettingsBM.myPrefs.useBloodFury == CRSettingsBM.CooldownPrefs.OnCoolDown
                || (CRSettingsBM.myPrefs.useBloodFury == CRSettingsBM.CooldownPrefs.Bosses && IsWoWBoss(Me.CurrentTarget)))
                && LastSpell != BLOOD_FURY
                && SpellManager.CanCast(BLOOD_FURY),
                new Action(ret =>
                {
                    SpellManager.Cast(BLOOD_FURY);
                    Logging.Write(Colors.Lime, BLOOD_FURY);
                    LastSpell = BLOOD_FURY;
                }));
        }
        Composite KillShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(KILL_SHOT)
                && !spellOnCooldown(KILL_SHOT)
                && Me.CurrentTarget.HealthPercent <= 20
                && LastSpell != KILL_SHOT
                && SpellManager.CanCast(KILL_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(KILL_SHOT);
                    Logging.Write(Colors.Lime, KILL_SHOT);
                    LastSpell = KILL_SHOT;
                }));
        }
        Composite Misdirection()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(MISDIRECTION)
                && CRSettingsBM.myPrefs.useMisdirection != CRSettingsBM.WhenMisdirection.Never
                && !spellOnCooldown(MISDIRECTION)
                && !buffExists(MISDIRECTION, Me)
                && (CRSettingsBM.myPrefs.useMisdirection == CRSettingsBM.WhenMisdirection.OnAggro
                && Me.CurrentTarget.ThreatInfo.RawPercent >= CRSettingsBM.myPrefs.misdirectionThreatInfo)
                && LastSpell != MISDIRECTION
                && SpellManager.CanCast(MISDIRECTION),
                new Action(ret =>
                {
                    Lua.DoString("RunMacroText('/cast [@focus,help][help][@pet,exists] Misdirection');");
                    Logging.Write(Colors.Lime, MISDIRECTION);
                    LastSpell = MISDIRECTION;
                }));
        }
        Composite MultiShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(MULTI_SHOT)
                && Me.FocusPercent >= 40
                && SpellManager.CanCast(MULTI_SHOT),
                new Action(ret =>
                {
                    if (!Me.GroupInfo.IsInParty
                        && SpellManager.HasSpell(MISDIRECTION)
                        && !spellOnCooldown(MISDIRECTION)
                        && !buffExists(MISDIRECTION, Me)
                        && !Me.CurrentTarget.Name.Contains("Dummy"))
                    {
                        Lua.DoString("RunMacroText('/cast [@focus,help][help][@pet,exists] Misdirection');");
                        SpellManager.Cast(MULTI_SHOT);
                        Logging.Write(Colors.LightBlue, MULTI_SHOT);
                        LastSpell = MULTI_SHOT;
                    }
                    else
                    {
                        SpellManager.Cast(MULTI_SHOT, Me.CurrentTarget);
                        Logging.Write(Colors.LightBlue, MULTI_SHOT);
                        LastSpell = MULTI_SHOT;
                    }
                }));
        }
        Composite ExplosiveTrap()
        {
            return new Decorator(ret => gotTarget
                && UnfriendlyUnits.Count() >= CRSettingsBM.myPrefs.startAoe
                && SpellManager.HasSpell(EXPLOSIVE_TRAP)
                && !spellOnCooldown(EXPLOSIVE_TRAP)
                && CRSettingsBM.myPrefs.useExplosiveTrap
                && buffExists(TRAP_LAUNCHER, Me)
                && LastSpell != EXPLOSIVE_TRAP
                && LastSpell != ICE_TRAP
                && LastSpell != SNAKE_TRAP,
                new Action(ret =>
                {
                    SpellManager.Cast(EXPLOSIVE_TRAP);
                    SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                    Logging.Write(Colors.LightBlue, EXPLOSIVE_TRAP);
                    LastSpell = EXPLOSIVE_TRAP;
                }));
        }
        Composite IceTrap()
        {
            return new Decorator(ret => gotTarget
                && UnfriendlyUnits.Count() >= CRSettingsBM.myPrefs.startAoe
                && SpellManager.HasSpell(ICE_TRAP)
                && !spellOnCooldown(ICE_TRAP)
                && CRSettingsBM.myPrefs.useIceTrap
                && buffExists(TRAP_LAUNCHER, Me)
                && LastSpell != EXPLOSIVE_TRAP
                && LastSpell != ICE_TRAP
                && LastSpell != SNAKE_TRAP,
                new Action(ret =>
                {
                    SpellManager.Cast(ICE_TRAP);
                    SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                    Logging.Write(Colors.LightBlue, ICE_TRAP);
                    LastSpell = ICE_TRAP;
                }));
        }
        Composite SnakeTrap()
        {
            return new Decorator(ret => gotTarget
                && UnfriendlyUnits.Count() >= CRSettingsBM.myPrefs.startAoe
                && SpellManager.HasSpell(SNAKE_TRAP)
                && !spellOnCooldown(SNAKE_TRAP)
                && CRSettingsBM.myPrefs.useSnakeTrap
                && buffExists(TRAP_LAUNCHER, Me)
                && LastSpell != EXPLOSIVE_TRAP
                && LastSpell != ICE_TRAP
                && LastSpell != SNAKE_TRAP,
                new Action(ret =>
                {
                    SpellManager.Cast(EXPLOSIVE_TRAP);
                    SpellManager.ClickRemoteLocation(Me.CurrentTarget.Location);
                    Logging.Write(Colors.LightBlue, SNAKE_TRAP);
                    LastSpell = SNAKE_TRAP;
                }));
        }
        Composite ExplosiveShotProc()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(EXPLOSIVE_SHOT)
                && buffExists(LOCK_AND_LOAD, Me)
                && SpellManager.CanCast(EXPLOSIVE_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(EXPLOSIVE_SHOT);
                    Logging.Write(Colors.Lime, EXPLOSIVE_SHOT);
                    LastSpell = EXPLOSIVE_SHOT;
                
                }));
        }
        Composite ExplosiveShot()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(EXPLOSIVE_SHOT)
                && !spellOnCooldown(EXPLOSIVE_SHOT) 
                && Me.FocusPercent >= 25
                && SpellManager.CanCast(EXPLOSIVE_SHOT),
                new Action(ret =>
                {
                    SpellManager.Cast(EXPLOSIVE_SHOT);
                    Logging.Write(Colors.Lime, EXPLOSIVE_SHOT);
                    LastSpell = EXPLOSIVE_SHOT;
                }));
        }
        Composite BlackArrow()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(BLACK_ARROW)
                && !spellOnCooldown(BLACK_ARROW)
                && !debuffExists(BLACK_ARROW, Me.CurrentTarget)
                && Me.FocusPercent >= 35
                && LastSpell != BLACK_ARROW
                && SpellManager.CanCast(BLACK_ARROW),
                new Action(ret =>
                {
                    SpellManager.Cast(BLACK_ARROW);
                    Logging.Write(Colors.Lime, BLACK_ARROW);
                    LastSpell = BLACK_ARROW;
                }));
        }
        Composite IceTrapKiting()
        {
            return new Decorator(ret => gotTarget
                && CRSettingsBM.myPrefs.useIceTrapKiting
                && SpellManager.HasSpell(ICE_TRAP)
                && !spellOnCooldown(ICE_TRAP)
                && LastSpell != ICE_TRAP
                && (Me.IsMoving
                && Me.MovementInfo.MovingBackward),
                new Action(ret =>
                {
                    WoWPoint myPresentLocation = Me.Location;
                    SpellManager.Cast(ICE_TRAP);
                    SpellManager.ClickRemoteLocation(myPresentLocation);
                    Logging.Write(Colors.LightBlue, ICE_TRAP);
                }));
        }
        #endregion shots

        #region pullsequence
        Composite pullSequence()
        {
            return new Decorator(ret => gotTarget,
                new Action(ret =>
                {
                    if (SpellManager.HasSpell(MISDIRECTION)
                        && !spellOnCooldown(MISDIRECTION)
                        && !buffExists(MISDIRECTION, Me)
                        && LastSpell != MISDIRECTION
                        && SpellManager.CanCast(MISDIRECTION))
                    {
                        Lua.DoString("RunMacroText('/cast [@focus,help][help][@pet,exists] Misdirection');");
                        Logging.Write(Colors.CornflowerBlue, "[Pull] " + MISDIRECTION + " Auto Shot");
                        LastSpell = MISDIRECTION;
                        SpellManager.Cast("Auto Shot");
                    }
                    else if (!SpellManager.HasSpell(MISDIRECTION)
                        && SpellManager.HasSpell(CONCUSSIVE_SHOT)
                        && !spellOnCooldown(CONCUSSIVE_SHOT)
                        && !debuffExists(CONCUSSIVE_SHOT, Me.CurrentTarget)
                        && LastSpell != CONCUSSIVE_SHOT
                        && SpellManager.CanCast(CONCUSSIVE_SHOT))
                    {
                        SpellManager.Cast(CONCUSSIVE_SHOT);
                        Logging.Write(Colors.CornflowerBlue, "[Pull] " + CONCUSSIVE_SHOT);
                        LastSpell = CONCUSSIVE_SHOT;
                    }
                    else if (SpellManager.HasSpell(ARCANE_SHOT)
                        && Me.FocusPercent >= 30
                        && SpellManager.CanCast(ARCANE_SHOT))
                    {
                        SpellManager.Cast(ARCANE_SHOT);
                        Logging.Write(Colors.CornflowerBlue, "[Pull] " + ARCANE_SHOT);
                        LastSpell = ARCANE_SHOT;
                    }
                    else if(SpellManager.CanCast("Auto Shot"))
                    {
                        SpellManager.Cast("Auto Shot");
                        Logging.Write(Colors.CornflowerBlue, "[Pull] Auto Shot");
                    }
                }));
        }
        #endregion pullsequence

        #region buffs
        Composite AspectIron()
        {
            return new Decorator(ret => SpellManager.HasSpell(ASPECT_OF_THE_IRON_HAWK)
                && !Me.Mounted
                && !Me.IsFlying
                && !buffExists(ASPECT_OF_THE_IRON_HAWK, Me)
                && LastSpell != ASPECT_OF_THE_IRON_HAWK
                && SpellManager.CanCast(ASPECT_OF_THE_IRON_HAWK),
                new Action(ret =>
                {
                    SpellManager.Cast(ASPECT_OF_THE_IRON_HAWK, Me);
                    Logging.Write(Colors.BlanchedAlmond, ASPECT_OF_THE_IRON_HAWK);
                    LastSpell = ASPECT_OF_THE_IRON_HAWK;
                }));
        }
        Composite AspectHawk()
        {
            return new Decorator(ret => SpellManager.HasSpell(ASPECT_OF_THE_HAWK)
                && !Me.Mounted
                && !Me.IsFlying
                && !SpellManager.HasSpell(ASPECT_OF_THE_IRON_HAWK)
                && !buffExists(ASPECT_OF_THE_HAWK, Me)
                && LastSpell != ASPECT_OF_THE_HAWK
                && SpellManager.CanCast(ASPECT_OF_THE_HAWK),
                new Action(ret =>
                {
                    SpellManager.Cast(ASPECT_OF_THE_HAWK, Me);
                    Logging.Write(Colors.BlanchedAlmond, ASPECT_OF_THE_HAWK);
                    LastSpell = ASPECT_OF_THE_HAWK;
                }));
        }
        Composite TrapLauncher()
        {
            return new Decorator(ret => SpellManager.HasSpell(TRAP_LAUNCHER)
                && !Me.Mounted
                && !Me.IsFlying
                && CRSettingsBM.myPrefs.autoTrapLauncher
                && !buffExists(TRAP_LAUNCHER, Me)
                && LastSpell != TRAP_LAUNCHER
                && SpellManager.CanCast(TRAP_LAUNCHER),
                new Action(ret =>
                {
                    SpellManager.Cast(TRAP_LAUNCHER, Me);
                    Logging.Write(Colors.BlanchedAlmond, TRAP_LAUNCHER);
                    LastSpell = TRAP_LAUNCHER;
                }));
        }
        #endregion buffs

        #region pet
        Composite takePetsTarget()
        {
            return new Decorator(ret => (Me.CurrentTarget == null || Me.CurrentTarget.IsDead || Me.CurrentTarget.IsFriendly)
                && Me.Pet != null 
                && Me.GotAlivePet 
                && Me.Pet.CurrentTarget != null,
                new Action(ret =>
                {
                    Me.Pet.CurrentTarget.Target();
                    Logging.Write(Colors.Orange, "Taking pet's target");
                }));
        }
        Composite MendPet()
        {
            return new Decorator(ret => gotTarget
                && Me.Pet != null
                && Me.GotAlivePet
                && SpellManager.HasSpell(MEND_PET)
                && !buffExists(MEND_PET, Me.Pet)
                && Me.Pet.HealthPercent <= CRSettingsBM.myPrefs.mendpetPercent
                && LastSpell != MEND_PET
                && SpellManager.CanCast(MEND_PET),
                new Action(ret =>
                {
                    SpellManager.Cast(MEND_PET);
                    Logging.Write(Colors.Orange, MEND_PET);
                    LastSpell = MEND_PET;
                }));
        }
        Composite CallPet()
        {
            return new Decorator(ret => Me.Pet == null
                && CRSettingsBM.myPrefs.autoCallPet
                && !Me.Mounted
                && !Me.IsFlying
                && !Me.IsOnTransport
                && !Me.OnTaxi
                && LastSpell != "CallPet",
                new Action(ret =>
                {
                    string myPet = "Call Pet " + CRSettingsBM.myPrefs.CallPetNr.ToString();
                    petPresenceTimer.Restart();
                    while (petPresenceTimer.ElapsedMilliseconds <= 2000) { };
                    SpellManager.Cast(myPet);
                    StyxWoW.SleepForLagDuration();
                    Logging.Write(Colors.Orange, "Trying to " + myPet);
                    LastSpell = "CallPet";
                    petPresenceTimer.Reset();

                }));
        }
        Composite RevivePet()
        {
            return new Decorator(ret => ((Me.Pet == null && LastSpell == "CallPet") || (Me.Pet != null && Me.Pet.IsDead))
                && !Me.Mounted
                && !Me.IsFlying
                && !Me.IsOnTransport
                && !Me.OnTaxi
                && !Me.IsMoving,
                new Action(ret =>
                {
                        petPresenceTimer.Restart();
                        while (petPresenceTimer.ElapsedMilliseconds <= 2000) { };

                        SpellManager.Cast("Revive Pet");
                        LastSpell = "Revive Pet";
                        Logging.Write(Colors.Orange, "Revive Pet");
                        StyxWoW.SleepForLagDuration();
                        petPresenceTimer.Reset();
                        LastSpell = "RevivePet";
                }));
        }
        #endregion pet

        #region dismount
        Composite Dismount()
        {
            return new Decorator(ret => !Me.IsFlying
                && Me.Mounted
                && CRSettingsBM.myPrefs.Movement
                && Me.Aggro,
                new Action(ret =>
                {

                    Logging.Write(Colors.CornflowerBlue, "Fire in the hole ! Dismounting !");
                    Lua.DoString("Dismount()");
                    if (Me.CurrentTarget != null)
                    {
                        Me.ClearTarget();
                    }
                }));
        }
        #endregion dismount

        #region GiftNaruu
        Composite GiftNaruu()
        {
            return new Decorator(ret => gotTarget
                && SpellManager.HasSpell(GIFT_OF_THE_NARUU)
                && !spellOnCooldown(GIFT_OF_THE_NARUU)
                && LastSpell != GIFT_OF_THE_NARUU
                && Me.HealthPercent <= CRSettingsBM.myPrefs.naruupercent
                && SpellManager.CanCast(GIFT_OF_THE_NARUU),
                new Action(ret =>
                {
                    SpellManager.Cast(GIFT_OF_THE_NARUU);
                    Logging.Write(Colors.Black, GIFT_OF_THE_NARUU);
                    LastSpell = GIFT_OF_THE_NARUU;
                }));
        }
        #endregion GiftNaruu
    }
}
